<template>
  <view
    class="uv-avatar"
    :class="[`uv-avatar--${shape}`]"
    :style="[{
      backgroundColor: (text || icon) ? (randomBgColor ? colors[colorIndex !== '' ? colorIndex : $uv.random(0, 19)] : bgColor) : 'transparent',
      width: $uv.addUnit(size),
      height: $uv.addUnit(size),
    }, $uv.addStyle(customStyle)]"
    @tap="clickHandler"
  >
    <slot>
      <!-- #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU  -->
      <open-data
        v-if="mpAvatar && allowMp"
        type="userAvatarUrl"
        :style="[{
          width: $uv.addUnit(size),
          height: $uv.addUnit(size)
        }]"
      />
      <!-- #endif -->
      <!-- #ifndef MP-WEIXIN && MP-QQ && MP-BAIDU  -->
      <template v-if="mpAvatar && allowMp"></template>
      <!-- #endif -->
      <uv-icon
        v-else-if="icon"
        :name="icon"
        :size="fontSize"
        :color="color"
      ></uv-icon>
      <uv-text
        v-else-if="text"
        :text="text"
        :size="fontSize"
        :color="color"
        align="center"
        customStyle="justify-content: center"
      ></uv-text>
      <image
        class="uv-avatar__image"
        v-else
        :class="[`uv-avatar__image--${shape}`]"
        :src="avatarUrl || defaultUrl"
        :mode="mode"
        @error="errorHandler"
        :style="[{
          width: $uv.addUnit(size),
          height: $uv.addUnit(size)
        }]"
      ></image>
    </slot>
  </view>
</template>

<script>
import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
import props from './props.js';
const base64Avatar =
  "";
/**
 * Avatar  头像
 * @description 本组件一般用于展示头像的地方，如个人中心，或者评论列表页的用户头像展示等场所。
 * @tutorial https://www.uvui.cn/components/avatar.html
 *
 * @property {String}			src				头像路径，如加载失败，将会显示默认头像(不能为相对路径)
 * @property {String}			shape			头像形状  （ circle (默认) | square）
 * @property {String | Number}	size			头像尺寸，可以为指定字符串(large, default, mini)，或者数值 （默认 40 ）
 * @property {String}			mode			头像图片的裁剪类型，与uni的image组件的mode参数一致，如效果达不到需求，可尝试传widthFix值 （默认 'scaleToFill' ）
 * @property {String}			text			用文字替代图片，级别优先于src
 * @property {String}			bgColor			背景颜色，一般显示文字时用 （默认 '#c0c4cc' ）
 * @property {String}			color			文字颜色 （默认 '#ffffff' ）
 * @property {String | Number}	fontSize		文字大小  （默认 18 ）
 * @property {String}			icon			显示的图标
 * @property {Boolean}			mpAvatar		显示小程序头像，只对百度，微信，QQ小程序有效  （默认 false ）
 * @property {Boolean}			randomBgColor	是否使用随机背景色  （默认 false ）
 * @property {String}			defaultUrl		加载失败的默认头像(组件有内置默认图片)
 * @property {String | Number}	colorIndex		如果配置了randomBgColor为true，且配置了此值，则从默认的背景色数组中取出对应索引的颜色值，取值0-19之间
 * @property {String}			name			组件标识符  （默认 'level' ）
 * @property {Object}			customStyle		定义需要用到的外部样式
 *
 * @event    {Function}        click       点击组件时触发   index: 用户传递的标识符
 * @example  <uv-avatar :src="src" mode="square"></uv-avatar>
 */
export default {
  name: 'uv-avatar',
  emits: ['click'],
  mixins: [mpMixin, mixin, props],
  data() {
    return {
      // 如果配置randomBgColor参数为true，在图标或者文字的模式下，会随机从中取出一个颜色值当做背景色
      colors: ['#ffb34b', '#f2bba9', '#f7a196', '#f18080', '#88a867', '#bfbf39', '#89c152', '#94d554', '#f19ec2',
        '#afaae4', '#e1b0df', '#c38cc1', '#72dcdc', '#9acdcb', '#77b1cc', '#448aca', '#86cefa', '#98d1ee',
        '#73d1f1',
        '#80a7dc'
      ],
      avatarUrl: this.src,
      allowMp: false
    }
  },
  watch: {
    // 监听头像src的变化，赋值给内部的avatarUrl变量，因为图片加载失败时，需要修改图片的src为默认值
    // 而组件内部不能直接修改props的值，所以需要一个中间变量
    src: {
      immediate: true,
      handler(newVal) {
        this.avatarUrl = newVal
        // 如果没有传src，则主动触发error事件，用于显示默认的头像，否则src为''空字符等的时候，会无内容展示
        if (!newVal) {
          this.errorHandler()
        }
      }
    }
  },
  computed: {
    imageStyle() {
      const style = {}
      return style
    }
  },
  created() {
    this.init()
  },
  methods: {
    init() {
      // 目前只有这几个小程序平台具有open-data标签
      // 其他平台可以通过uni.getUserInfo类似接口获取信息，但是需要弹窗授权(首次)，不合符组件逻辑
      // 故目前自动获取小程序头像只支持这几个平台
      // #ifdef MP-WEIXIN || MP-QQ || MP-BAIDU
      this.allowMp = true
      // #endif
    },
    // 判断传入的name属性，是否图片路径，只要带有"/"均认为是图片形式
    isImg() {
      return this.src.indexOf('/') !== -1
    },
    // 图片加载时失败时触发
    errorHandler() {
      this.avatarUrl = this.defaultUrl || base64Avatar
    },
    clickHandler() {
      this.$emit('click', this.name)
    }
  }
}
</script>

<style lang="scss" scoped>
@import '@/uni_modules/uv-ui-tools/libs/css/components.scss';

.uv-avatar {
  @include flex;
  align-items: center;
  justify-content: center;

  &--circle {
    border-radius: 100px;
  }

  &--square {
    border-radius: 4px;
  }

  &__image {
    &--circle {
      border-radius: 100px;
    }

    &--square {
      border-radius: 4px;
    }
  }
}
</style>
